/**
  ******************************************************************************
  * File Name          : lcdbsp.c
  * Description        : This file provides code for the configuration
  *                      of the USART instances.
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "dwlcd.h"
#include "tskcfg.h"
#include "bsp.h"

volatile static Dw_RxStateType  dw_rx_state = DW_STATE_HEAD1;
static Dw_RxBufType dw_rxbuf_isr;

/* USART6 init function */
void Lcd_BspInit(void)
{
  timer_parameter_struct timer_initpara;
  
	rcu_periph_clock_enable(RCU_GPIOE);
	rcu_periph_clock_enable(RCU_UART7);
  rcu_periph_clock_enable(DWLCD_TIMER_CLOCK);
  
  rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
  
  
	gpio_af_set(GPIOE, GPIO_AF_8, GPIO_PIN_0);
	gpio_af_set(GPIOE, GPIO_AF_8, GPIO_PIN_1);
	
	/* configure USART0 Tx as alternate function push-pull */
	gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0);

	/* configure USART0 Rx as alternate function push-pull */
	gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_1);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
	
	/* USART configure */
	usart_deinit(UART7);
	usart_baudrate_set(UART7, 115200u);
	usart_word_length_set(UART7, USART_WL_8BIT);
	usart_parity_config(UART7, USART_PM_NONE);
	usart_stop_bit_set(UART7, USART_STB_1BIT);
	usart_receive_config(UART7, USART_RECEIVE_ENABLE);
	usart_transmit_config(UART7, USART_TRANSMIT_ENABLE);
	usart_halfduplex_disable(UART7);
	usart_synchronous_clock_disable(UART7);
//	usart_receiver_timeout_threshold_config(UART7, 10000);/* 200M主频下,115200波特率超时时间约为每个计数8.68us */
//	usart_receiver_timeout_disable(UART7);
	
  
  timer_deinit(DWLCD_TIMER);
	timer_struct_para_init(&timer_initpara);
	timer_initpara.prescaler         = 40000U;
  timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
  timer_initpara.counterdirection  = TIMER_COUNTER_UP;
  timer_initpara.period            = 100;
  timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
  timer_initpara.repetitioncounter = 0U;
	timer_init(DWLCD_TIMER, &timer_initpara);
	timer_auto_reload_shadow_enable(DWLCD_TIMER);
  timer_single_pulse_mode_config(DWLCD_TIMER, TIMER_SP_MODE_SINGLE);
  
	timer_interrupt_flag_clear(DWLCD_TIMER, TIMER_INT_FLAG_UP);
	timer_flag_clear(DWLCD_TIMER, TIMER_FLAG_UP);
  
  
	nvic_irq_enable(UART7_IRQn, DWLCD_UART_IRQ_PRIORITY, 0);
  nvic_irq_enable(DWLCD_TIMER_IRQn, DWLCD_TIMER_IRQ_PRIORITY, 0);


	usart_interrupt_enable(UART7, USART_INT_RBNE);
	usart_interrupt_disable(UART7, USART_INT_RT);
	timer_interrupt_enable(DWLCD_TIMER, TIMER_INT_UP);
  
  timer_disable(DWLCD_TIMER);
  
	usart_enable(UART7);
}

void Lcd_UartSendStr(const char *buf)
{
	uint32_t i;

	for(i=0; buf[i]!='\0'; i++)
	{
    USART_DATA(UART7) = (buf[i]& (uint16_t)0x01FFU);
    while(!(USART_STAT0(UART7) & USART_STAT0_TBE));
	}
}

void Lcd_UartSendBuf(const uint8_t *buf, uint32_t len)
{
	uint32_t i;
  
	for(i=0; i<len; i++)
	{
		USART_DATA(UART7) = (buf[i]& (uint16_t)0x01FFU);
    while(!(USART_STAT0(UART7) & USART_STAT0_TBE));
	}
}

/**
  * @brief This function handles USART6 global interrupt.
  */
void UART7_IRQHandler(void)
{
  uint8_t dat;
  
	if(usart_interrupt_flag_get(UART7, USART_INT_FLAG_RBNE) != RESET)
	{
    TIMER_CTL0(DWLCD_TIMER) &= ~(uint32_t)TIMER_CTL0_CEN;
    
		dat = USART_DATA(UART7);
    
    switch(dw_rx_state)
    {
      case DW_STATE_HEAD1:
        if(dat == HEADER1)
        {
          dw_rx_state = DW_STATE_HEAD2;
        }
        break;
      
      case DW_STATE_HEAD2:
        if(dat == HEADER2)
        {
          dw_rx_state = DW_STATE_LENGTH;
        }
        break;
      
      case DW_STATE_LENGTH:
        if(dat < DWLCD_FRM_MAXLEN+1)
        {
          dw_rxbuf_isr.len = dat - 1;
          dw_rx_state = DW_STATE_CMD;
        }
        else
        {
          dw_rx_state = DW_STATE_HEAD1;
        }
        break;
      
      case DW_STATE_CMD:
        if(dat == 0x83u)
        {
          dw_rxbuf_isr.cmd = dat;
          dw_rxbuf_isr.rxcnt = 0;
          dw_rx_state = DW_STATE_DATA;
        }
        else
        {
          dw_rx_state = DW_STATE_HEAD1;
        }
        break;
      
      case DW_STATE_DATA:
        dw_rxbuf_isr.dat[dw_rxbuf_isr.rxcnt++] = dat;
        if(dw_rxbuf_isr.rxcnt >= dw_rxbuf_isr.len)
        {
          if(Dw_Rx_Qhd != NULL)   /* make sure tasks are created */
          {
            xQueueSendFromISR(Dw_Rx_Qhd, &dw_rxbuf_isr, NULL);
          }
          dw_rx_state = DW_STATE_HEAD1;
        }
        break;
        
      default:
        dw_rx_state = DW_STATE_HEAD1;
        break;
    }
    
    TIMER_CNT(DWLCD_TIMER) = (uint32_t)0;
		TIMER_CTL0(DWLCD_TIMER) |= (uint32_t)TIMER_CTL0_CEN;
	}
	
//	if(usart_interrupt_flag_get(UART7, USART_INT_FLAG_RT) != RESET)
//	{
//		usart_interrupt_flag_clear(UART7, USART_INT_FLAG_RT);
//	}
}

void DWLCD_TIMER_IRQHandler(void)
{
	if(timer_interrupt_flag_get(DWLCD_TIMER, TIMER_INT_FLAG_UP) != RESET)
	{
		timer_interrupt_flag_clear(DWLCD_TIMER, TIMER_INT_FLAG_UP);
    
    dw_rx_state = DW_STATE_HEAD1;
	}
}

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
